package com.chen.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Slf4j
//@Aspect 注解表示当前类是一个切面类
@Component
public class MyAspect1 {
    @Pointcut("execution(* com.chen.service.Impl.*.*(..))")//定义全局切入点，提高代码复用性
    public void pt() {}//切入点表达式，如果是private则表示只有当前类才能匹配到，否则其他类都可以匹配
    // 切面表达式: execution(返回值类型 包名.类名.方法名(参数))


    // 前置通知: 目标方法执行前执行
    @Before("pt()")
    public void before() {
        log.info("before.....");
    }


    // 环绕通知: 目标方法执行前后都执行
    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        log.info("around before.....");
        Object result = pjp.proceed();
        log.info("around after....");
        return result;
    }

    // 后置通知: 目标方法执行后执行
    @After("pt()")
    public void after() {
        log.info("after.....");
    }

    //AfterReturning:返回通知,在目标方法正常返回后被执行，只有目标方法没有抛出异常，才会被执行
    @AfterReturning("pt()")
    public void afterReturning() {
        log.info("afterReturning......");
    }

    //AfterThrowing:异常通知,在目标方法抛出异常后被执行
    @AfterThrowing("pt()")
    public void afterThrowing() {
        log.info("afterThrowing.....");
    }
}
